//////////////////////////////////////////////
// BlurProgramsTracker.h
//
//////////////////////////////////////////////

/// Defines / Macros -------------------------

#pragma once

/// Forward decl -----------------------------

namespace nkGraphics
{
	class Program ;
	class System ;
}

/// Includes ---------------------------------

// nkAstraeus
#include "../../Utils/ProgramTracker.h"

#include "BlurComplexEffectInfo.h"

// nkMemory
#include <NilkinsMemory/Pointers/UniquePtr.h>

// Standards
#include <unordered_map>

/// Internals --------------------------------

namespace nkAstraeus
{
	struct BlurProgramsIdGenerator
	{
		static unsigned long long generate (const BlurComplexEffectInfo& info) ;
	} ;

	struct BlurProgramsNameGenerator
	{
		constexpr static const char* name = "NILKINS_BLUR_PROGRAM_" ;
	} ;

	struct BlurProgramsEntry
	{
		nkMemory::UniquePtr<nkGraphics::Program> _programHorizontal ;
		nkMemory::UniquePtr<nkGraphics::Program> _programVertical ;
		unsigned int _count = 0 ;
	} ;
}

/// Class ------------------------------------

namespace nkAstraeus
{
	class BlurProgramsTracker final
	{
		public :

			// Constructor, destructor
			BlurProgramsTracker (nkGraphics::System* graphicsSystem) noexcept ;
			~BlurProgramsTracker () ;

			// Memory management
			std::pair<nkGraphics::Program*, nkGraphics::Program*> getPrograms (const BlurComplexEffectInfo& info) ;
			void releasePrograms (const BlurComplexEffectInfo& info) ;


		private :

			// Constructors
			BlurProgramsTracker (const BlurProgramsTracker&) = delete ;
			BlurProgramsTracker (BlurProgramsTracker&&) = delete ;

			// Operators
			BlurProgramsTracker& operator= (const BlurProgramsTracker&) = delete ;
			BlurProgramsTracker& operator= (BlurProgramsTracker&&) = delete ;

		private :

			// Attributes
			nkGraphics::System* _graphicsSystem ;

			// Memory of programs
			std::unordered_map<unsigned long long, BlurProgramsEntry> _memory ;
	} ;
}